// Cargo.toml 中需要添加以下依赖：
// [dependencies]
// reqwest = { version = "0.11", features = ["stream", "json"] }
// serde = { version = "1.0", features = ["derive"] }
// serde_json = "1.0"
// futures = "0.3"
// tauri = "1"

use futures::StreamExt;
use serde_json::json;
#[tauri::command]
pub async fn chat_stream() -> Result<(String, String), String> {
    // 请替换为实际的 API Key 与 base URL
    let api_key = "sk-6cc5cedeb6934044aa929ba43a07bc9d";
    let base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions";
    let model = "qwq-plus";

    // 系统提示（思考过程）信息
    let system_msg = r#"
数据移动类型：
输入（E），是从用户穿越被度量系统的范围传输数据到系统内部，这里提到的用户既包括系统的使用人员，也包括其他软件或者硬件系统。
输出（X），是一个数据组从一个功能处理通过范围移动到需要它的用户。
读（R），是从永久性的存储设备读取数据。
写（W），是存储数据到永久性的存储设备。

例如我的一个功能点为  导入合作社考勤数据，需要将其拆分成三条为E、R、X
功能用户需求  触发事件    功能过程    子过程描述   数据移动类型  数据组 数据属性
导入合作社考勤数据	打开合作社考勤页面	导入合作社考勤数据	用户点击导入合作社考勤数据	E	合作社考勤导入文件	文件地址、文件名称、文件类型
导入合作社考勤数据	打开合作社考勤页面	导入合作社考勤数据	解析用户上传的文件为合作社考勤数据	R	文件信息、解析信息	文件地址、文件名称、文件类型、预算编号、预算项目、合同、合同编号、总工作量、开始时间、结束时间
导入合作社考勤数据	打开合作社考勤页面	导入合作社考勤数据	将解析后的数据保存在数据库中 	W	文件信息、解析信息	文件地址、文件名称、文件类型、预算编号、预算项目、合同、合同编号、总工作量、开始时间、结束时间
导入合作社考勤数据	打开合作社考勤页面	导入合作社考勤数据	将文件解析的结果展示在页面中	X	文件解析信息	预算编号、预算项目、合同、合同编号、总工作量、开始时间、结束时间

每个功能点都必须含有E、R、W、X，并且只有一个
子过程描述不能相同
"#;

    // 用户发送的内容
    let user_content = r#"
这是功能点
1、和作社考勤数据文件上传接口：支持合同（项目）负责人在需管平台上传和作社导出的考勤数据文件（如Excel/CSV）。
2、文件格式校验：校验上传文件是否符合模板格式（如列名、数据类型、必填字段）。
3、数据解析与清洗：解析导入文件内容，处理异常数据（如重复记录、无效日期、非数字工时）。
4、数据关联关系校验：校验和作社考勤数据中的人员ID、项目编码是否与需管平台现有数据匹配。
5、导入进度与结果反馈：显示导入进度条，导入完成后返回成功/失败记录明细（如成功条数、错误条数及原因）。
"#;

    // 构造请求体
    let body = json!({
        "model": model,
        "messages": [
            { "role": "system", "content": system_msg },
            { "role": "user", "content": user_content }
        ],
        "stream": true
    });

    // 创建 HTTP 客户端，并发送 POST 请求
    let client = reqwest::Client::new();
    let response = client
        .post(base_url)
        .header("Authorization", format!("Bearer {}", api_key))
        .header("Content-Type", "application/json")
        .json(&body)
        .send()
        .await
        .map_err(|e| format!("Request error: {}", e))?;

    // 检查响应状态
    if !response.status().is_success() {
        let status = response.status();
        let text = response.text().await.unwrap_or_default();
        return Err(format!("Request failed with status {}: {}", status, text));
    }

    // 用于累计“思考过程”（reasoning_content）与“完整回复”（answer_content）
    let mut reasoning_content = String::new();
    let mut answer_content = String::new();
    let mut is_answering = false;

    // 获取响应流（以 byte stream 的方式）
    let mut stream = response.bytes_stream();

    // 持续读取每一块数据
    while let Some(item) = stream.next().await {
        let chunk = item.map_err(|e| format!("Stream error: {}", e))?;
        let chunk_str = std::str::from_utf8(&chunk).unwrap_or("");
        // 可能一块数据中包含多行
        for line in chunk_str.lines() {
            // 流式响应一般以 "data: " 开头
            if line.starts_with("data: ") {
                let data_str = line.trim_start_matches("data: ").trim();
                if data_str == "[DONE]" {
                    break;
                }
                // 解析 JSON 数据
                let json_data: serde_json::Value = match serde_json::from_str(data_str) {
                    Ok(val) => val,
                    Err(err) => {
                        eprintln!("JSON parse error: {}", err);
                        continue;
                    }
                };

                if let Some(choice) = json_data.get("choices").and_then(|arr| arr.get(0)) {
                    if let Some(delta) = choice.get("delta") {
                        // 检查 reasoning_content 并处理
                        if let Some(reasoning) = delta.get("reasoning_content") {
                            let text = reasoning.as_str().unwrap_or("");
                            print!("{}", text);
                            reasoning_content.push_str(text);
                        }
                        // 分开独立处理 content 字段，而不是用 else if
                        if let Some(content) = delta.get("content") {
                            let text = content.as_str().unwrap_or("");
                            if !text.is_empty() && !is_answering {
                                println!("\n================ 完整回复 ================\n");
                                is_answering = true;
                            }
                            print!("{}", text);
                            answer_content.push_str(text);
                        }
                    }

                }
            }
        }
    }

    // 返回思考过程与完整回复（可以在前端进一步处理）
    Ok((reasoning_content, answer_content))
}
